package com.ruoyi.job.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.job.domain.*;
import com.ruoyi.job.mapper.*;
import com.ruoyi.system.api.domain.MaterialInfojk;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import com.ruoyi.common.core.utils.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.List;
import java.util.Set;

/**
 * 定时任务调度测试
 * 
 * @author ruoyi
 */
@Component("ryTask")
public class RyTask
{
    @Autowired
    private ShOrderDsMapper shOrderDsMapper;
    @Autowired
    private SysUserDsMapper sysUserDsMapper;
    @Autowired
    private ShProductDsMapper shProductDsMapper;
    @Autowired
    private ShMarketDsMapper shMarketDsMapper;
    @Autowired
    private MaterialOrderDsMapper infoOrderDsMapper;
    @Autowired
    private MaterialInfoDsMapper infoDsMapper;
    @Autowired
    private MaterialjkOrderDsMapper infojkOrderDsMapper;
    @Autowired
    private MaterialInfojkDsMapper infojkDsMapper;
    @Resource
    private StringRedisTemplate myRedisTemplate;
    private CloseableHttpClient wxPayClient;
    private static CertificatesManager certificatesManager;
    private static final String mchid = "1573954551";
    private static final String mchSerialNo = "7B7D3FEFD602BD69DE92A98A603F400C8CA38403";
    private static final String apiV3Key = "xiaoshudingv38888888888888888888";
    private static final String privateKeyForDecrypt = "-----BEGIN PRIVATE KEY-----\n" +
            "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDN6DUEtqlml1PN\n" +
            "LT5kQFfbr8UTDCAyjHK3N3w2AjACTcvoKoHYItz4+GeUk1jdOvk7GyssWXMtElkC\n" +
            "16T9REKQMu4yExYGRUV8kjkq/4gToRDNwpv7BxltnyQTW2LLIGkN2PHUUtqMDLOO\n" +
            "Oca97757DkHbUOXpVjwvU0F83BQ0akxznNp0swr+YgB4VAAsloLmJ6sKWcNBbP2o\n" +
            "fQLB4gOn7N7zdD5mLxIPkg7QE6K6ZDL75sjkmbdQm+tI0ri9JsJFEohDY6fUxjXc\n" +
            "mYH2Lur93CBH8FmOHQn7xlZZqEi2qH9tQPjnDstUREe0BNDHICYdxFYJZ+tFRGYF\n" +
            "83rqswqbAgMBAAECggEAKDWWVOtOvWgDx2d0baNbBN2YQJX3m6dtp3XAXdOjiG+k\n" +
            "yBu0634zZLMtlwgHLHyduvsdPTXilgSlOTbfU04HKZ2ogkLT5DmWzjLH0yu/aQXl\n" +
            "AClmyGikgJG5O8Z2zm/v0/JvlyTu5LZ+QeHqe6Dbs7AfEDMGEsDyU9OQUE+x6mIW\n" +
            "A5O9CO4rv90fo49M1xJNC50OrHNCETDCIseIW56J+6CJsE64TODSAZJEdBb9VIB1\n" +
            "GrXq0EDo1UhdJ9smIUqKlvn6CGCg4NX/iP905V+cDD/qbNb+X87Tp9yxYIDYcwsQ\n" +
            "v4bYLomyqi78cHXCxd4koJE98tmMqJ8tW9WjB2BWsQKBgQDsBohIDGnv94f209S4\n" +
            "9xXkP5L08V5BpahUnaBUBu6ieig4OyLjxrqOAO7QkaQDSxNnVtMkzryHdb6b6PDi\n" +
            "Fz7OiIlyePmma5dfE+NIuyrmx9wL4/EOU9vYQtSYbxcyVaBKg5dmTe4WtuwMBm2d\n" +
            "z726vlKSW2bCQhOj3dEWzqlOtwKBgQDfVSlc59dk6ujuEIkIHJiASaTyt4dRWhn3\n" +
            "lX2GYYTPbsSVvYzpQNFkhkA6J/ayDEOuarooEAdU79gFPRIWFtSNK4qgC5IvyfDI\n" +
            "KW1VlA860oFoB1B7dYUYdveO2FHHSfVJtEMfWj2GplphiPscK5MEYe1p0uZ8Yc77\n" +
            "yRl+DaX/PQKBgQC+9DICCHkU+jD4Uz2BP/ZoKb8diMH3Xq0neDekg89BiI9NnxqF\n" +
            "Kdz40mxkNdB6EZ1rN+Wvm8sP1QUXYoiwgpn/wpthD9r694UKGS8DQtpcyEmRHSOD\n" +
            "sfjlqHwTr50WzgvW/UvaKyZ7HhcvS2wYB2C62ww2+NfURl1ZcDafuydjVQKBgG3b\n" +
            "yIMJEK112Kryu1WgK2w/zcIPgaME/W0KvjqSUfBv/ofiPCSpW9dlKsbwzat72Pc9\n" +
            "TOFUMScY7Fx3VCRFirz+xCxCROD5J1Zu+nd0Y6F912ZC4tY4UwZbzx8XTfMIcH6X\n" +
            "C8WqcEWCI0eDSHLtBF7NhSnfMr3Qpy64F7AoKpXJAoGAbwdbxzpDXTekdOn7Z8V2\n" +
            "YvTNTLLxD3wbmegITNXGQOukd1bUINiZQH6inRUzmyae2YYLCh/1uobQN2oHtSB7\n" +
            "jGKAscA1HlkBzniP1ow597oJOvI9tzBkbJWNz5xk4+5BFtJa+uM5bBEBYcdghMzo\n" +
            "YKZKGSQ865sxXiIZ/pisG0A=\n" +
            "-----END PRIVATE KEY-----";

    public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i)
    {
        System.out.println(StringUtils.format("执行多参方法： 字符串类型{}，布尔类型{}，长整型{}，浮点型{}，整形{}", s, b, l, d, i));
    }

    public void ryParams(String params)
    {
        System.out.println("执行有参方法：" + params);
        try {
            this.orderQuery();
        }catch (Exception e) {}
    }

    public void ryNoParams()
    {
        System.out.println("执行无参方法");
    }

    private void orderQuery() throws Exception {
        Set<String> keys = myRedisTemplate.keys("*pay");
        System.out.println(keys);
        String queryURL = "https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/";
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(privateKeyForDecrypt);
        // 获取证书管理器实例
        certificatesManager = CertificatesManager.getInstance();
        // 向证书管理器增加需要自动更新平台证书的商户信息
        certificatesManager.putMerchant(mchid, new WechatPay2Credentials(mchid,
                        new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),
                apiV3Key.getBytes(StandardCharsets.UTF_8));
        wxPayClient = WechatPayHttpClientBuilder.create()
                .withMerchant(mchid, mchSerialNo, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(certificatesManager.getVerifier(mchid)))
                .build();
        keys.forEach((key)->{
            String out_trade_no = myRedisTemplate.opsForValue().get(key);
            System.out.println("out_trade_no:"+out_trade_no);
            String url = queryURL.concat(out_trade_no).concat("?mchid=").concat(mchid);
            HttpGet httpGet = new HttpGet(url);
            httpGet.setHeader("Accept", "application/json");
            // 2.完成签名并执行请求
            CloseableHttpResponse response = null;
            try {
                response = wxPayClient.execute(httpGet);
                // 1.获取请求码
                int statusCode = response.getStatusLine().getStatusCode();
                // 2.获取返回值 String 格式
                final String bodyAsString = EntityUtils.toString(response.getEntity());
                if (statusCode == 200) {
                    JSONObject json = JSON.parseObject(bodyAsString);
                    String trade_state = json.getString("trade_state");
                    String out_trade_noY = json.getString("out_trade_no");
                    String amountStr = json.getString("amount");
                    JSONObject jsonSub = JSON.parseObject(amountStr);
                    if ("SUCCESS".equalsIgnoreCase(trade_state)) {
                        ShOrderDs shOrderParam = new ShOrderDs();
                        shOrderParam.setOrderNo(out_trade_noY);
                        List<ShOrderDs> orderlist = this.shOrderDsMapper.selectShOrderList(shOrderParam);
                        if (null!=orderlist&&orderlist.size()>0) {
                            for (ShOrderDs entity : orderlist) {
                                entity.setStatus(1);
                                this.shOrderDsMapper.updateShOrder(entity);
                                this.setMarket(entity);
                            }
                        }else {
                            MaterialOrderDs infoOrderParam = new MaterialOrderDs();
                            infoOrderParam.setOrderNo(out_trade_noY);
                            List<MaterialOrderDs> listInfo = infoOrderDsMapper.selectMaterialOrderList(infoOrderParam);
                            if (null!=listInfo&&listInfo.size()>0) {
                                for (MaterialOrderDs entity:listInfo) {
                                    entity.setStatus(1);
                                    infoOrderDsMapper.updateMaterialOrder(entity);
                                    this.setMarketInfo(entity);
                                }
                            }else {
                                MaterialjkOrderDs infojkOrderParam = new MaterialjkOrderDs();
                                infojkOrderParam.setOrderNo(out_trade_noY);
                                List<MaterialjkOrderDs> listInfojk = infojkOrderDsMapper.selectMaterialjkOrderList(infojkOrderParam);
                                if (null!=listInfojk&&listInfojk.size()>0) {
                                    for (MaterialjkOrderDs entity:listInfojk) {
                                        entity.setStatus(1);
                                        infojkOrderDsMapper.updateMaterialjkOrder(entity);
                                        this.setMarketInfojk(entity);
                                    }
                                }
                            }
                        }
                        myRedisTemplate.delete(key);
                    }
                } else {
                    // 其他异常，微信也没有返回数据，这就需要具体排查了
                    throw new IOException("request failed");
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private void setMarket(ShOrderDs entity) {
        Long orderUserId = entity.getCreateBy();
        SysUserDs sysUser = sysUserDsMapper.selectUserById(orderUserId);
        Long inviteId = sysUser.getInviteId();
        Long pinviteId = sysUser.getPinviteId();
        ShProductDs product = shProductDsMapper.selectShProductById(entity.getProductId());
        if (null!=product.getDiscount()&&product.getDiscount().compareTo(BigDecimal.ZERO)>0) {
            BigDecimal amount = product.getProductPrice().multiply(BigDecimal.valueOf(entity.getNum()));
            if (null!=product.getProductDiscount()&&product.getProductDiscount().doubleValue()>0) {
                amount = amount.multiply(product.getProductDiscount());
            }
            if (null!=inviteId&&inviteId>0) {
                ShMarketDs market = new ShMarketDs();
                market.setShopId(product.getShopId());
                market.setProductId(product.getId());
                market.setAmount(amount);
                market.setAccount(product.getDiscount());
                BigDecimal marketAmount = market.getAmount().multiply(market.getAccount());
                market.setMarketAmount(marketAmount);
                market.setCreateBy(inviteId);
                market.setCreateTime(DateUtils.getNowDate());
                shMarketDsMapper.insertShMarket(market);
            }
            if (null!=pinviteId&&pinviteId>0) {
                BigDecimal pdiscount = product.getDiscount();
                if (null!=product.getDiscountBl()&&product.getDiscountBl().doubleValue()>0) {
                    pdiscount = pdiscount.multiply(product.getDiscountBl());
                }
                ShMarketDs market = new ShMarketDs();
                market.setShopId(product.getShopId());
                market.setProductId(product.getId());
                market.setAmount(amount);
                market.setAccount(pdiscount);
                BigDecimal marketAmount = market.getAmount().multiply(market.getAccount());
                market.setMarketAmount(marketAmount);
                market.setCreateBy(pinviteId);
                market.setCreateTime(DateUtils.getNowDate());
                shMarketDsMapper.insertShMarket(market);
            }
        }
    }

    private void setMarketInfo(MaterialOrderDs entity) {
        Long orderUserId = entity.getCreateBy();
        SysUserDs sysUser = sysUserDsMapper.selectUserById(orderUserId);
        Long inviteId = sysUser.getInviteId();
        Long pinviteId = sysUser.getPinviteId();
        MaterialInfoDs product = infoDsMapper.selectMaterialInfoById(entity.getMaterialId());
        if (null!=product.getDiscount()&&product.getDiscount().compareTo(BigDecimal.ZERO)>0) {
            SysUserDs createUser = sysUserDsMapper.selectUserById(product.getUserId());
            BigDecimal amount = entity.getRealAmount();
            if (null!=product.getDiscount()&&product.getDiscount().doubleValue()>0) {
                amount = amount.multiply(product.getDiscount());
            }
            if (null!=inviteId&&inviteId>0) {
                ShMarketDs market = new ShMarketDs();
                market.setShopId(createUser.getDeptId());
                market.setProductId(product.getId());
                market.setAmount(amount);
                market.setAccount(product.getDiscount());
                BigDecimal marketAmount = market.getAmount().multiply(market.getAccount());
                market.setMarketAmount(marketAmount);
                market.setCreateBy(inviteId);
                market.setCreateTime(DateUtils.getNowDate());
                shMarketDsMapper.insertShMarket(market);
            }
            if (null!=pinviteId&&pinviteId>0) {
                BigDecimal pdiscount = product.getDiscount();
                if (null!=product.getDiscountBl()&&product.getDiscountBl().doubleValue()>0) {
                    pdiscount = pdiscount.multiply(product.getDiscountBl());
                }
                ShMarketDs market = new ShMarketDs();
                market.setShopId(createUser.getDeptId());
                market.setProductId(product.getId());
                market.setAmount(amount);
                market.setAccount(pdiscount);
                BigDecimal marketAmount = market.getAmount().multiply(market.getAccount());
                market.setMarketAmount(marketAmount);
                market.setCreateBy(pinviteId);
                market.setCreateTime(DateUtils.getNowDate());
                shMarketDsMapper.insertShMarket(market);
            }
        }
    }

    private void setMarketInfojk(MaterialjkOrderDs entity) {
        Long orderUserId = entity.getCreateBy();
        SysUserDs sysUser = sysUserDsMapper.selectUserById(orderUserId);
        Long inviteId = sysUser.getInviteId();
        Long pinviteId = sysUser.getPinviteId();
        MaterialInfojk product = infojkDsMapper.selectMaterialInfojkById(entity.getMaterialId());
        if (null!=product.getDiscount()&&product.getDiscount().compareTo(BigDecimal.ZERO)>0) {
            SysUserDs createUser = sysUserDsMapper.selectUserById(product.getUserId());
            BigDecimal amount = entity.getRealAmount();
            if (null!=product.getDiscount()&&product.getDiscount().doubleValue()>0) {
                amount = amount.multiply(product.getDiscount());
            }
            if (null!=inviteId&&inviteId>0) {
                ShMarketDs market = new ShMarketDs();
                market.setShopId(createUser.getDeptId());
                market.setProductId(product.getId());
                market.setAmount(amount);
                market.setAccount(product.getDiscount());
                BigDecimal marketAmount = market.getAmount().multiply(market.getAccount());
                market.setMarketAmount(marketAmount);
                market.setCreateBy(inviteId);
                market.setCreateTime(DateUtils.getNowDate());
                shMarketDsMapper.insertShMarket(market);
            }
            if (null!=pinviteId&&pinviteId>0) {
                BigDecimal pdiscount = product.getDiscount();
                if (null!=product.getDiscountBl()&&product.getDiscountBl().doubleValue()>0) {
                    pdiscount = pdiscount.multiply(product.getDiscountBl());
                }
                ShMarketDs market = new ShMarketDs();
                market.setShopId(createUser.getDeptId());
                market.setProductId(product.getId());
                market.setAmount(amount);
                market.setAccount(pdiscount);
                BigDecimal marketAmount = market.getAmount().multiply(market.getAccount());
                market.setMarketAmount(marketAmount);
                market.setCreateBy(pinviteId);
                market.setCreateTime(DateUtils.getNowDate());
                shMarketDsMapper.insertShMarket(market);
            }
        }
    }
}
